#ifndef ORBITVIRTUALMACHINE_H
#define ORBITVIRTUALMACHINE_H
#include <string>
#include <vector>
#include <map>
#include <QHash>

//объявляется указатель под именем pt2Member
// Объявляем указатель на функцию-член класса SomeClass
//typedef void (OrbitVirtualMachine::*DFP)(int, int, int);
//typedef void (OrbitVirtualMachine::*SFP)(int, int, int);

/*
 мише: мне нужны снаружи следующие функции:
1. задать входной файл.
2. задать конфигурацию (номер задачи) для этого файла.
3. задать остальные входные порты (скоростьХ и скоростьУ).
4. Отработать один шаг машины.
5. вернуть выходные порты.
*/

class OrbitVirtualMachine
{
public:
    OrbitVirtualMachine();
    virtual ~OrbitVirtualMachine();
    void setInputPort(int number, double val);
    /// Scenario Configuration Numbers
    void setScenario(int number);
    void nextStep();
    virtual void nextCompiledStep()
        {nextStep();}
    void getPort(int number, double &val);
    /// Open file obf
    void openFile(const std::string &fileName);
    void setLog(const std::string &file);
    void generateCpp(const std::string &saveTo);
    virtual std::string getStatusString();
protected:
    void init();
    void statsOutput();
    void parseCommand(const char *buff, int index);
    char m_buff[12];
    unsigned int m_index;
    int m_count;

    bool m_logEnabled;
    std::string m_logFile;
    std::vector<unsigned long int> m_code;
    std::vector<double> m_data;

    QHash<int, double> m_inReg;
    QHash<int, double> m_outReg;
    bool m_status;

    /// Функции двух переменных
    void executeD(int op, int r1, int r2);
    void executeS(int op, int imm, int r1);
    void dAdd(int r1, int r2);
    void dSub(int r1, int r2);
    void dMult(int r1, int r2);
    void dDiv(int r1, int r2);
    void dPhi(int r1, int r2);
    void dOutput(int r1, int r2);

    /// Функции одной (почти) переменной
    void sNoop(int imm, int r1);
    void sCmpz(int imm, int r1);
    void sSqrt(int imm, int r1);
    void sCopy(int imm, int r1);
    void sInput(int imm, int r1);

    /// Utilits
    std::string printD(int op, int r1, int r2);
    std::string printS(int op, int imm, int r1);
};

class OVMBin1:public OrbitVirtualMachine
{
public:
    void nextCompiledStep();
    std::string getStatusString();
};

class OVMBin2:public OrbitVirtualMachine
{
public:
    void nextCompiledStep();
    std::string getStatusString();
};

class OVMBin3:public OrbitVirtualMachine
{
public:
    void nextCompiledStep();
    std::string getStatusString();
};

class OVMBin4:public OrbitVirtualMachine
{
public:
    void nextCompiledStep();
    std::string getStatusString();
};

#endif // ORBITVIRTUALMACHINE_H
